package com.apes.scm.masterdata.party.model;

import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.DefaultPersistListener;
import com.apes.framework.jpa.Model;
import com.apes.framework.jpa.Name;
import com.apes.framework.jpa.comment.Comment;
import com.apes.framework.jpa.generator.ApesGenerator;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.finance.model.BankAccount;
import com.apes.scm.masterdata.finance.model.PaymentMethodType;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SelectBeforeUpdate;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

//import com.apes.scm.rbac.model.User;

/**
 * 功能：当事人
 *
 * @author xul
 * @create 2018-01-23 11:11
 */
@Getter
@Setter
@SelectBeforeUpdate
@DynamicInsert
@DynamicUpdate
@Entity
@EntityListeners(DefaultPersistListener.class)
@Table(name = Party.CONST_TABLE_NAME)
//@Inheritance(strategy = InheritanceType.JOINED)
public class Party extends Model {
    public static final String CONST_TABLE_NAME = "mas_party";

    @Id
    @Column(name = "id")
    @ApesGenerator(code = CONST_TABLE_NAME, name = "当事人")
    @Comment("当事人编码")
    private long id;   //当事人编码

    @Name
    @Column(name = "name", nullable = false, length = 120)
    @Comment("当事人名称")
    private String name; //当事人名称

    @Column(name = "abbreviation", length = 32)
    @Comment("简称")
    private String abbreviation; //简称

    @Column(name = "party_Type", nullable = false, length = 32)
    @Comment("当事人类型(person：个人；corporate：法人单位)")
    private String partyType; //当事人类型(person：个人；corporate：法人单位)

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="payment_method_type", referencedColumnName="id")
    @Comment("收款方式")
    private PaymentMethodType paymentMethodType;

    @Column(name = "bank", length = 200)
    @Comment("开户行")
    private String bank; //开户行

    @Column(name = "bank_account", length = 32)
    @Comment("银行帐号")
    private String bankAccount; //银行帐号

    @Column(name = "invoice_title", length = 200)
    @Comment("发票抬头")
    private String invoiceTitle;  //发票抬头

    @Column(name = "invoice_address", length = 256)
    @Comment("发票地址")
    private String invoiceAddress;  //发票地址

    @Column(name = "invoice_phone", length = 256)
    @Comment("发票电话")
    private String invoicePhone;  //发票电话

    @Column(name = "invoice_number", length = 256)
    @Comment("发票税号")
    private String invoiceNumber;  //发票税号

    @Column(name = "ORIGIN", length = 20)
    @Comment("外部ID")
    private String origin; //外部ID

    @Column(name = "settlement_center", columnDefinition = "number(1,0) default 0")
    @Comment("区域结算中心标记")
    private boolean settlementCenter = false;

    @Column(name = "operator_sign", columnDefinition = "number(1,0) default 0")
    @Comment("运营商标记")
    private boolean operatorSign = false;

    // 所属运营商
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "belong_operator", referencedColumnName = "id")
    @Comment("所属运营商")
    private PartyRole belongOperator;

    @Transient
    private boolean warehousingCompany = false;

    public boolean isWarehousingCompany() {
        return SpringManager.getBean(PartyRoleRepository.class).findAll(JpaDsl.toCriteriaByEq("role.id", "Warehousing", "party.id", id)).size() > 0?true:false;
    }

    @OneToMany(mappedBy = "party", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<PartyIdentification> partyIdentifications = new HashSet(); //当事人身份标识

    public Set<PartyIdentification> getPartyIdentifications() {
        if (partyIdentifications == null) return null;
        for (PartyIdentification partyIdentification : partyIdentifications) {
            partyIdentification.setParty(this);
        }
        return partyIdentifications;
    }

    @OneToMany(mappedBy = "party", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<PartyRole> partyRoles = new HashSet(); //当事人角色

    public Set<PartyRole> getPartyRoles() {
        if (partyRoles == null) return null;
        for (PartyRole partyRole : partyRoles) {
            partyRole.setParty(this);
        }
        return partyRoles;
    }

    // 增加角色类型
    public void addPartyRole(String partyType, String code) {
        PartyRole partyRole = new PartyRole();
        RoleType roleType = new RoleType();
        roleType.setId(partyType);
        partyRole.setId(code);
        partyRole.setRole(roleType);
        partyRole.setParty(this);
        if (partyRoles == null) {
            partyRoles = new HashSet();
        }
        partyRoles.add(partyRole);
        this.setPartyRoles(partyRoles);
    }
    // 增加角色类型
    public void addPartyRole(String partyType, String code,boolean fin) {
        PartyRole partyRole = new PartyRole();
        RoleType roleType = new RoleType();
        roleType.setId(partyType);
        partyRole.setId(code);
        partyRole.setRole(roleType);
        partyRole.setParty(this);
        partyRole.setFin(fin);
        if (partyRoles == null) {
            partyRoles = new HashSet();
        }
        partyRoles.add(partyRole);
        this.setPartyRoles(partyRoles);
    }
    // 增加角色类型
    public void addPartyRoleByType(String partyType, Party party) {
        PartyRole partyRole = new PartyRole();
        RoleType roleType = new RoleType();
        roleType.setId(partyType);
        partyRole.setRole(roleType);
        partyRole.setParty(this);
        PartySerialNumber serialNumber = new PartySerialNumber();
        serialNumber = serialNumber.checkParty(party);
        String roleId = String.format("%4d", serialNumber.getCompanyId()).replace(" ", "0");
        partyRole.setId(partyType.equals("Supplier")?("G"+roleId):(partyType.equals("Customer")?("K"+roleId):roleId));
        if (partyRoles == null) {
            partyRoles = new HashSet();
        }
        partyRoles.add(partyRole);
    }

    @OneToOne(mappedBy = "party", cascade = CascadeType.ALL, orphanRemoval = true)
    private Corporate corporate;  //法人公司信息

    public Corporate getCorporate() {
        if (corporate != null) {
            corporate.setParty(this);
        }
        return corporate;
    }

    @OneToOne(mappedBy = "party", cascade = CascadeType.ALL, orphanRemoval = true)
    private Person person;  //人员信息

    public Person getPerson() {
        if (person != null) {
            person.setParty(this);
        }
        return person;
    }

    @Transient
    public String getRoleCode(String roleId) {
        Optional<PartyRole> optional = this.getPartyRoles().stream()
                .filter(partyRole -> partyRole.getRole().getId().equalsIgnoreCase(roleId))
                .findFirst();
        PartyRole role = null;
        if (optional != null) role = optional.get();
        if (role != null) return role.getId();
        return null;
    }

    @Transient
    public boolean isRole(String roleId) {
        return this.getPartyRoles().stream()
                .filter(partyRole -> partyRole.getRole().getId().equalsIgnoreCase(roleId))
                .count() > 0;
    }


    // 公司编码
    @Name
    @Transient
    private String companyCode;

    // 供应商编码
    @Transient
    private String supplierCode;

    // 客户编码
    @Name
    @Transient
    private String customerCode;

    /**
     * 获取人员编码
     */
    @Name
    @Transient
    private String personCode;

    /**
     * 获取接入商
     */
    @Name
    @Transient
    private AccessProvider accessProvider;

//    @JSONField(serialize = false)
//    @OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
//    private Set<User> users;

    /***
     * 功能：获取手机号
     * @return
     */
    public String queryMobileNumber() {
        if (person == null) return null;
        return person.getMobileNumber();
    }

    public PartyRole getPatyRoleByType(String partyType) {
        PartyRole partyRole = getPartyRoleByType(partyType);
        if (Objects.isNull(partyRole)) throw new RuntimeException("未找到对应类型角色！");
        return partyRole;
    }

    public PartyRole getPartyRoleByType(String partyType) {
        return partyRoles.stream().filter((x) -> x.getRole().getId().equals(partyType)).findAny()
                .orElse(null);
    }

    @OneToMany(mappedBy = "partyId", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<BankAccount> bankAccounts = new HashSet();  //当事人收款信息

    public Set<BankAccount> getBankAccounts() {
        if (bankAccounts.isEmpty() && bankAccounts.size() == 0) return null;
        for (BankAccount bankAccount : bankAccounts) {
            bankAccount.setPartyId(this);
        }
        return bankAccounts;
    }

}
